var limit = 20;//全局分页设置为20条

Ext.ux.PagingToolbar = Ext.extend(Ext.PagingToolbar, {
	moveNext : function(){
		var tpage=this.store.getTotalCount()/this.pageSize;
		var cpage=this.cursor/this.pageSize+1;
		if(tpage<=cpage){
			this.doLoad(this.cursor - this.pageSize);
		}else{
			this.doLoad(this.cursor+this.pageSize);
		}
	},
	 // private
    onLoad : function(store, r, o){
        if(!this.rendered){
            this.dsLoaded = [store, r, o];
            return;
        }
        var p = this.getParams();
        this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
        var d = this.getPageData(), ap = d.activePage, ps = d.pages;

        this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
        this.inputItem.setValue(ap);
        this.first.setDisabled(ap == 1);
        this.prev.setDisabled(ap == 1);
        this.next.setDisabled(ap >= ps);
        this.last.setDisabled(ap >= ps);
        this.refresh.enable();
        this.updateInfo();
        this.fireEvent('change', this, d);
    }
});
/**    
 * @class Ext.tree.TreeCheckNodeUI    
 * @extends Ext.tree.TreeNodeUI    
 *     
 * 对 Ext.tree.TreeNodeUI 进行checkbox功能的扩展,后台返回的结点信息不用非要包含checked属性    
 *     
 * 扩展的功能点有：    
 * 一、支持只对树的叶子进行选择    
 *    只有当返回的树结点属性leaf = true 时，结点才有checkbox可选    
 *    使用时，只需在声明树时，加上属性 onlyLeafCheckable: true 既可，默认是false    
 *     
 * 二、支持对树的单选    
 *    只允许选择一个结点    
 *    使用时，只需在声明树时，加上属性 checkModel: "single" 既可    
 *     
 * 二、支持对树的级联多选     
 *    当选择结点时，自动选择该结点下的所有子结点，以及该结点的所有父结点（根结点除外），特别是支持异步，当子结点还没显示时，会从后台取得子结点，然后将其选中/取消选中    
 *    使用时，只需在声明树时，加上属性 checkModel: "cascade" 既可    
 *     
 * 三、添加"check"事件    
 *    该事件会在树结点的checkbox发生改变时触发    
 *    使用时，只需给树注册事件,如：    
 *    tree.on("check",function(node,checked){...});    
 *     
 * 默认情况下，checkModel为'multiple'，也就是多选，onlyLeafCheckable为false，所有结点都可选    
 *     
 * 使用方法：在loader里加上 baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} 既可.    
 * 例如：    
 *   var tree = new Ext.tree.TreePanel({    
 *      el:'tree-ct',    
 *      width:568,    
 *      height:300,    
 *      checkModel: 'cascade',   //对树的级联多选    
 *      onlyLeafCheckable: false,//对树所有结点都可选    
 *      animate: false,    
 *      rootVisible: false,    
 *      autoScroll:true,    
 *      loader: new Ext.tree.DWRTreeLoader({    
 *          dwrCall:Tmplt.getTmpltTree,    
 *          baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI } //添加 uiProvider 属性    
 *      }),    
 *      root: new Ext.tree.AsyncTreeNode({ id:'0' })    
 *  });    
 *  tree.on("check",function(node,checked){alert(node.text+" = "+checked)}); //注册"check"事件    
 *  tree.render();    
 *     
 */     
     
Ext.ux.TreeCheckNodeUI = function() {      
    //'multiple':多选; 'single':单选; 'cascade':级联多选      
    this.checkModel = 'multiple';      
          
    //only leaf can checked      
    this.onlyLeafCheckable = false;      
          
    Ext.ux.TreeCheckNodeUI.superclass.constructor.apply(this, arguments);      
};      
     
Ext.extend(Ext.ux.TreeCheckNodeUI, Ext.tree.TreeNodeUI, {      
     
    renderElements : function(n, a, targetNode, bulkRender){      
        var tree = n.getOwnerTree();      
        this.checkModel = tree.checkModel || this.checkModel;      
        this.onlyLeafCheckable = tree.onlyLeafCheckable || false;      
              
        // add some indent caching, this helps performance when rendering a large tree      
        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';      
     
    var cb = (!this.onlyLeafCheckable || a.leaf);      
        var href = a.href ? a.href : Ext.isGecko ? "" : "#";      
        var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',      
            '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",      
            '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',      
            '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',      
            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',      
            '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',      
             a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",      
            '<ul class="x-tree-node-ct" style="display:none;"></ul>',      
            "</li>"].join('');
        var nel;      
        if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){      
            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);      
        }else{      
            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);      
        }      
              
        this.elNode = this.wrap.childNodes[0];      
        this.ctNode = this.wrap.childNodes[1];      
        var cs = this.elNode.childNodes;      
        this.indentNode = cs[0];
        this.ecNode = cs[1];      
        this.iconNode = cs[2];      
        var index = 3;      
        if(cb){      
            this.checkbox = cs[3];      
            Ext.fly(this.checkbox).on('click', this.check.createDelegate(this,[null]));      
            index++;      
        }      
        this.anchor = cs[index];      
        this.textNode = cs[index].firstChild;      
    },      
          
    // private      
    check : function(checked){      
        var n = this.node;      
        var tree = n.getOwnerTree();      
        this.checkModel = tree.checkModel || this.checkModel;      
              
        if( checked === null ) {      
            checked = this.checkbox.checked;      
        } else {      
            this.checkbox.checked = checked;      
        }      
              
        n.attributes.checked = checked;      
        tree.fireEvent('check', n, checked);      
              
        if(!this.onlyLeafCheckable && this.checkModel == 'cascade'){      
            var parentNode = n.parentNode;      
            if(parentNode !== null) {      
                this.parentCheck(parentNode,checked);      
            }      
            if( !n.expanded && !n.childrenRendered ) {      
                n.expand(false,false,this.childCheck);      
            }      
            else {      
                this.childCheck(n);      
            }      
        }else if(this.checkModel == 'single'){      
            var checkedNodes = tree.getChecked();      
            for(var i=0;i<checkedNodes.length;i++){      
                var node = checkedNodes[i];      
                if(node.id != n.id){      
                    node.getUI().checkbox.checked = false;      
                    node.attributes.checked = false;      
                    tree.fireEvent('check', node, false);      
                }      
            }      
        }      
              
    },      
          
    // private      
    childCheck : function(node){      
        var a = node.attributes;      
        if(!a.leaf) {      
            var cs = node.childNodes;      
            var csui;      
            for(var i = 0; i < cs.length; i++) {      
                csui = cs[i].getUI();      
                if(csui.checkbox.checked ^ a.checked)      
                    csui.check(a.checked);      
            }      
        }      
    },      
          
    // private      
    parentCheck : function(node ,checked){      
        var checkbox = node.getUI().checkbox;      
        if(typeof checkbox == 'undefined')return ;      
        if(!(checked ^ checkbox.checked))return;      
        if(!checked && this.childHasChecked(node))return;      
        checkbox.checked = checked;      
        node.attributes.checked = checked;      
        node.getOwnerTree().fireEvent('check', node, checked);      
              
        var parentNode = node.parentNode;      
        if( parentNode !== null){      
            this.parentCheck(parentNode,checked);      
        }      
    },      
          
    // private      
    childHasChecked : function(node){      
        var childNodes = node.childNodes;      
        if(childNodes || childNodes.length>0){      
            for(var i=0;i<childNodes.length;i++){      
                if(childNodes[i].getUI().checkbox.checked)      
                    return true;      
            }      
        }      
        return false;      
    },      
          
    toggleCheck : function(value){      
        var cb = this.checkbox;      
        if(cb){      
            var checked = (value === undefined ? !cb.checked : value);      
            this.check(checked);      
        }      
    }      
});



Ext.ux.BillTreePanel = Ext.extend(Ext.tree.TreePanel, {
	region : 'west',//布局
	width : 175,//宽度
	rootVisible : false, //隐藏root节点
	split : true, //分割线可拖动
	animate : true, //展开折叠有动画效果
	border : false, //不显示边框
	lines : true, //不显示节点连线
	autoScroll:true,//滚动条
	docheck:true
	,listeners:{
		"checkchange":function(node,ischecked){
			if(this.docheck){
				this.docheck=false;
				if(node.isLeaf()){
					if(node.parentNode){
						if(this.getChecked(null,node.parentNode).length==1){
							node.parentNode.ui.toggleCheck(ischecked);
						}
					}
				}else{
					if(!node.isExpanded())node.expand();
					var nn;
					for(var n in node.childNodes){
						nn=node.childNodes[n].ui;
						if(nn){
							nn.toggleCheck(ischecked);
						}
					}
				}
				this.docheck=true;
			}
		}
	}
});
Ext.reg('billTreePanel', Ext.ux.BillTreePanel);

Ext.grid.ActionColumn2 = Ext.extend(Ext.grid.Column, {
    header: '&#160;',
    actionIdRe: /x-action-col-(\d+)/,
    altText: '',
    constructor: function(cfg) {
        var me = this,
            items = cfg.items || (me.items = [me]),
            l = items.length,
            i,
            item;
        Ext.grid.ActionColumn2.superclass.constructor.call(me, cfg);
        me.renderer = function(v, meta) {
            v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
            meta.css += ' x-action-col-cell';
            if(v){
            	v="";
                for (i = 0; i < l; i++) {
                    item = items[i];
                    v+= '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
                        '" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
                        ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
                        ((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
                }
            }else{
            	v="";
            }
            return v;
        };
    },
    destroy: function() {
        delete this.items;
        delete this.renderer;
        return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
    },
    processEvent : function(name, e, grid, rowIndex, colIndex){
        var m = e.getTarget().className.match(this.actionIdRe),
            item, fn;
        if (m && (item = this.items[parseInt(m[1], 10)])) {
            if (name == 'click') {
                (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
            } else if ((name == 'mousedown') && (item.stopSelection !== false)) {
                return false;
            }
        }
        return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
    }
});
Ext.grid.Column.types["billActionColumn"]=Ext.grid.ActionColumn2;

Ext.ux.BillCombox = Ext.extend(Ext.form.ComboBox, {
	valueField : 'id',
	displayField : 'text',
	mode : 'local',
	editable : false, //不允许输入,点击弹出下拉框
	forceSelection : true,//设置只能从列表中选取
	selectOnFocus : true,
	anchor : '100%',
	triggerAction : 'all'
});
Ext.reg('billCombox', Ext.ux.BillCombox);

//获得包含中文的字符长度
Ext.fucCheckCHLength = function(strTemp) {
	var i, sum;
	sum = 0;
	for (i = 0; i < strTemp.length; i++) {
		if ((strTemp.charCodeAt(i) >= 0) && (strTemp.charCodeAt(i) <= 255))
			sum = sum + 1;
		else
			sum = sum + 2;
	}
	return sum;
};

//增加 Ext 的 Vtype验证
Ext
		.apply(
				Ext.form.VTypes,
				{
					
					daterange : function(val, field) {
				        var date = field.parseDate(val);
				
				        if(!date){
				            return false;
				        }
				        if (field.startDateField && (!this.dateRangeMax || (date.getTime() != this.dateRangeMax.getTime()))) {
				            var start = Ext.getCmp(field.startDateField);
				            start.setMaxValue(date);
				            start.validate();
				            this.dateRangeMax = date;
				        }
				        else if (field.endDateField && (!this.dateRangeMin || (date.getTime() != this.dateRangeMin.getTime()))) {
				            var end = Ext.getCmp(field.endDateField);
				            end.setMinValue(date);
				            end.validate();
				            this.dateRangeMin = date;
				        }
				        
				        return true;
				    },
					password : function(val, field) {
						if (field.initialPassField) {
							var pwd = Ext.getCmp(field.initialPassField);
							return (val == pwd.getValue());
						}
						return true;
					},
					passwordText : '两次输入的密码不一致！',

					chinese : function(val, field) {
						var reg = /^[\u4e00-\u9fa5]+$/i;
						if (!reg.test(val)) {
							return false;
						}
						return true;
					},
					chineseText : '请输入中文',
					minlength : function(val, field) {
						try {
							if (Ext.fucCheckCHLength(val) >= parseInt(field.minLength))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					minlengthText : '输入值过短！<br>注：一个中文字符算两个字符的长度！',

					maxlength : function(val, field) {
						try {
							if (Ext.fucCheckCHLength(val) <= parseInt(field.maxLength))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					maxlengthText : '输入值过长！<br>注：一个中文字符算两个字符的长度！',

					age : function(val, field) {
						try {
							if (parseInt(val) >= 18 && parseInt(val) <= 100)
								return true;
							return false;
						} catch (err) {
							return false;
						}
					},
					ageText : '年龄输入有误',

					alphanumchinese: function(val, field) {
						try {
							var pat=new RegExp("[^a-zA-Z0-9\_\[\]\u4e00-\u9fa5]","i");
							if(pat.test(val))return false;
							return true;
						} catch (e) {
							return false;
						}
					},
					alphanumchineseText: '请输入英文字母,数字,中文，其它字符是不允许的.',

					alphanum : function(val, field) {
						try {
							if (!/\W/.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					alphanumText : '请输入英文字母或是数字,其它字符是不允许的.',

					url : function(val, field) {
						try {
							if (/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i
									.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					urlText : '请输入有效的URL地址.',

					ftp : function(val, field) {
						try {
							if (/^(ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i
									.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					ftpText : '请输入有效的FTP地址.',

					max : function(val, field) {
						try {
							if (parseFloat(val) <= parseFloat(field.max))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					maxText : '超过最大值',

					min : function(val, field) {
						try {
							if (parseFloat(val) >= parseFloat(field.min))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					minText : '小于最小值',

					datecn : function(val, field) {
						try {
							var regex = /^(\d{4})-(\d{2})-(\d{2})$/;
							if (!regex.test(val))
								return false;
							var d = new Date(val.replace(regex, '$1/$2/$3'));
							return (parseInt(RegExp.$2, 10) == (1 + d
									.getMonth()))
									&& (parseInt(RegExp.$3, 10) == d.getDate())
									&& (parseInt(RegExp.$1, 10) == d
											.getFullYear());
						} catch (e) {
							return false;
						}
					},
					datecnText : '请使用这样的日期格式: yyyy-mm-dd. 例如:2008-06-20.',

					integer : function(val, field) {
						try {
							if (/^[-+]?[\d]+$/.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					integerText : '请输入正确的整数',

					ip : function(val, field) {
						try {
							if ((/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
									.test(val)))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					ipText : '请输入正确的IP地址,如：127.1.1.1',

					phone : function(val, field) {
						try {
							if (/^((0[1-9]{3})?(0[12][0-9])?[-])?\d{6,8}$/
									.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					phoneText : '请输入正确的电话号码,如:0920-29392929',

					mobilephone : function(val, field) {
						try {
							if (/(^0?[1][358][0-9]{9}$)/.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					mobilephoneText : '请输入正确的手机号码',

					alpha : function(val, field) {
						try {
							if (/^[a-zA-Z]+$/.test(val))
								return true;
							return false;
						} catch (e) {
							return false;
						}
					},
					alphaText : '请输入英文字母'
				});